#!/usr/bin/env python
# coding: utf-8

# # RFM模型构建

# In[1]:


import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import os


# In[2]:


os.chdir(r'C:\Users\Administrator\Desktop\python文档\EvChargingUsageAnalysis-master\Data')


# In[3]:


df = pd.read_csv('Derivational_User_Data.csv',encoding = 'UTF-8', low_memory = False)
df.head(5)
df['Last_Start_Date'] = pd.to_datetime(df['Last_Start_Date'], errors='coerce')


# R值构造

# In[4]:


r = df.groupby('User ID')['Last_Start_Date'].max().reset_index()
r.head()


# In[5]:


r['R'] = (pd.to_datetime('2021-1-1') - r['Last_Start_Date']).dt.days  # 由于数据集原因没有取当前日期
r = r[['User ID','R']]
r.head()


# F值构造

# In[6]:


#引入日期标签辅助列
df['日期标签'] = df['Last_Start_Date'].astype(str).str[:10]

#把单个用户一天内订单合并
dup_f = df.groupby(['User ID','日期标签'])['Last_Start_Date'].count().reset_index()

#对合并后的用户统计频次
f = dup_f.groupby('User ID')['Last_Start_Date'].count().reset_index()
f.columns = ['User ID','F']
f.head()


# 构造M值

# In[7]:


com_m = pd.DataFrame()
#计算用户平均支付金额
com_m['User ID'] = df['User ID']
com_m['M'] = df['Fee_mean']
com_m.head()


# RFM合并

# In[8]:


rfm = pd.merge(r,com_m,left_on = 'User ID',right_on = 'User ID',how = 'inner')
rfm = pd.merge(rfm,f,left_on = 'User ID',right_on = 'User ID',how = 'inner')
rfm = rfm[['User ID','R','F','M']]
rfm.head()


# In[9]:


rfm['R_Score'] = pd.qcut(rfm['R'], 4, labels=range(4, 0, -1))
rfm['F_Score'] = pd.cut(rfm['F'], 4, labels=range(1, 5))
rfm['M_Score'] = pd.qcut(rfm['M'], 4, labels=range(1, 5))
rfm.head()


# In[10]:


rfm['R是否大于均值'] = (rfm['R_Score'].astype(float) > rfm['R_Score'].astype(float).mean()) * 1
rfm['F是否大于均值'] = (rfm['F_Score'].astype(float) > rfm['F_Score'].astype(float).mean()) * 1
rfm['M是否大于均值'] = (rfm['M_Score'].astype(float) > rfm['M_Score'].astype(float).mean()) * 1
rfm['RFM_Score'] = rfm.R是否大于均值.astype(str) + rfm.F是否大于均值.astype(str) + rfm.M是否大于均值.astype(str)
rfm.head()


# In[11]:


#判断R/F/M是否大于均值
def transform_label(x):
    label = None
    if x == 111:
        label = '重要价值客户'
    elif x == 110:
        label = '消费潜力客户'
    elif x == 101:
        label = '频次深耕客户'
    elif x == 100:
        label = '新客户'
    elif x == 11:
        label = '重要价值流失预警客户'
    elif x == 10:
        label = '一般客户'
    elif x == 1:
        label = '高消费唤回客户'
    elif x == 0:
        label = '流失客户'
    return label


# In[20]:


rfm['人群类型'] = rfm['RFM_Score'].astype(int).apply(transform_label)
rfm.head(5)


# In[13]:


#人数统计
count = rfm['人群类型'].value_counts().reset_index()
count.columns = ['客户类型','人数']
count['人数占比'] = count['人数'] / count['人数'].sum()
count


# In[14]:


rfm['购买总金额'] = rfm['F'] * rfm['M']
mon = rfm.groupby('人群类型')['购买总金额'].sum().reset_index()
mon.columns = ['客户类型','消费金额']
mon['金额占比'] = mon['消费金额'] / mon['消费金额'].sum()
mon


# In[15]:


result = pd.merge(count,mon,left_on = '客户类型',right_on = '客户类型')
result
res = result


# In[16]:


res.to_excel('客户分群统计结果表.xlsx', index=False)
rfm.to_excel('客户分群结果表.xlsx', index=False)


# In[17]:


res['人数占比']


# In[24]:


plt.figure()
plt.pie(res['人数占比'],autopct='%.5f%%',labels=res['客户类型'],explode=(0, 0, 0, 0.2, -0.6, 0.6)) #pie为饼图，需要传入的是一个 Seires
plt.title('不同客群人数占比图')
plt.rcParams['font.sans-serif']=['SimHei']  #字体
plt.rcParams['font.size']=14  #字体大小
plt.rcParams['figure.figsize']=[8,8]   #正圆
plt.savefig('不同客群人数占比图.png')


# In[25]:


plt.figure()
plt.pie(res['金额占比'],autopct='%.5f%%',labels=res['客户类型'],explode=(0,0,0,0.2,-0.6,0.6)) #pie为饼图，需要传入的是一个 Seires
plt.title('不同客群消费金额占比图')
plt.rcParams['font.sans-serif']=['SimHei']  #字体
plt.rcParams['font.size']=14  #字体大小
plt.rcParams['figure.figsize']=[8,8]   #正圆
plt.savefig('不同客群消费金额占比图.png')


# In[ ]:




